package org.dei.perla.sys.device.fpc;

import java.lang.reflect.InvocationTargetException;

import org.dei.perla.parser.expressions.*;
import org.dei.perla.utils.dataconverter.annotations.*;
import org.dei.perla.parser.util.DefinedTypes;

public class FPCDataStructureImpl extends FPCDataStructure {

	public FPCDataStructureImpl(AbstractData root) {
		super();
		this.root = root;

	}

	@Override
	public Constant<?> getAttributeByName(String parName)
			throws ClassNotFoundException, InstantiationException,
			IllegalAccessException, UnaccessibleFieldException,
			MappingClassNotFoundException, IllegalArgumentException,
			InvocationTargetException {
		Constant<?> parameter = null;
		Object methodResult = root.lookForParameter(parName);
		if (methodResult == null) {
			parameter = new ConstantNull();
		} else if (methodResult.getClass().isAnnotationPresent(
				MappingClass.class)) {
			String mappingClass = methodResult.getClass().getAnnotation(
					MappingClass.class).mapping();
			DefinedTypes dt = DefinedTypes.getInstance();
			if (dt.containsUserDefinedKey(mappingClass)) {
				Class c = Class.forName(dt.getUserDefinedType(mappingClass),
						true, methodResult.getClass().getClassLoader());
				parameter = (ConstantUserDefined<Object>) c.newInstance();
			} else {
				throw new MappingClassNotFoundException();
			}
		} else {
			if (methodResult instanceof Integer) {
				// System.out.println(""+((Integer) methodResult).intValue());
				parameter = new ConstantInteger(((Integer) methodResult)
						.intValue());
			} else if (methodResult instanceof int[]) {
				parameter = new ConstantVectorInteger((int[]) methodResult);
			} else if (methodResult instanceof Float) {
				parameter = new ConstantFloat(((Float) methodResult)
						.floatValue());
			} else if (methodResult instanceof double[]) {
				parameter = new ConstantVectorFloat((double[]) methodResult);
			} else if (methodResult instanceof String) {
				parameter = new ConstantString((String) methodResult);
			} else if (methodResult instanceof Boolean) {
				parameter = new ConstantLogic(((Boolean) methodResult)
						.booleanValue());
			} else if (methodResult instanceof byte[]) {
				parameter = new ConstantBlob((byte[]) methodResult);
			} else {
				throw new UnaccessibleFieldException();
			}
		}
		return parameter;
	}

	@Override
	protected Object getDataStructure(String parStructureIdentifier) {
		// return root????
		return null;
	}

	public static void main(String args[]) {
		org.dei.perla.sys.device.plugnplay.plugnplaymanager.Compiler.main(args);
		FPCDataStructureImpl fpcDataStructureImpl = new FPCDataStructureImpl(
				(AbstractData) new org.dei.perla.sys.device.fpc.testDevice.Test());
		try {
			System.out.println(fpcDataStructureImpl.getAttributeByName(
					"q_prova").toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
